﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using System.Globalization;


namespace Comp476Project
{
    class Team
    {
        public List<Entity> assets;
        public Color teamColor;
        public Model minionMod, championMod,HQmod, towerMod, barracksMod;
        public Map map;
        Matrix projection;
        public Entity HQ, leftBarrack,midBarrack, rightBarrack ;
        public float HQsize, towerSize, barrackSize;

        public int squadTimer, spawnCount, champTimer, champElapsed;
        public int TIMER = 15000;
        public Champion champion;
        public bool champ;

        public int elapsedTime ;
        
        public Tower hqT1, hqT2, midT1, midT2, leftT1, leftT2, rightT1, rightT2;

        public Vector3 spawnPoint1, spawnPoint2,spawnPoint3;
        public ContentManager Content;
        //=======HP===============
        Primitives3D.CubePrimitive healthBar;
        float hpBarScale;
        float hpBarHeight;
        float hpBarPercent;
        Matrix healthWorldRed;
        Matrix healthWorldGreen;

        public ParticleSystem effects;
        Primitives3D.SpherePrimitive sphere;
       
        public Team(GraphicsDevice GraphicsDevice,Matrix proj, ContentManager con, Color c, Map m) 
        {
           
            elapsedTime = champElapsed= spawnCount = 0;
            champTimer = 15000;
            squadTimer = TIMER;
            Content = con;
            projection = proj;
            assets = new List<Entity>();
            teamColor = c;
            map = m;
            HQsize = 0.025f;
            towerSize = 0.015f;
            barrackSize = 0.02f;
            sphere = new Primitives3D.SpherePrimitive(GraphicsDevice, 1, 4);
            #region teamBlue
            if (teamColor == Color.Blue) 
            {

                
                minionMod = Content.Load<Model>("blueChar");
                HQmod = Content.Load<Model>("models/blueHQ");
                towerMod = Content.Load<Model>("models/blueTower");
                barracksMod = Content.Load<Model>("models/blueBarracks");


                HQ = new Entity(sphere,projection, HQmod, new Vector3(0.002f, 0.04f, -0.781f));
                HQ.size = HQsize;
                HQ.maxHealth = 5000;
                HQ.health = HQ.maxHealth;
                assets.Add(HQ);//adding HQ

                //adding towers
                hqT1 = new Tower(sphere, projection, towerMod, new Vector3(0.046f, 0.04f, -0.712f));
                hqT1.size = towerSize;
                assets.Add(hqT1);//adding

                hqT2 = new Tower(sphere, projection, towerMod, new Vector3(-0.046f, 0.04f, -0.712f));
                hqT2.size = towerSize;
                assets.Add(hqT2);//adding

                midT1 = new Tower(sphere, projection, towerMod, new Vector3(-0.038f, 0.014f, -0.35f));
                midT1.size = towerSize;
                assets.Add(midT1);//adding

                midT2 = new Tower(sphere, projection, towerMod, new Vector3(0.033f, 0.014f, -0.176f));
                midT2.size = towerSize;
                assets.Add(midT2);//adding

                leftT1 = new Tower(sphere, projection, towerMod, new Vector3(0.243f, 0.014f, -0.42f));
                leftT1.size = towerSize;
                assets.Add(leftT1);//adding

                leftT2 = new Tower(sphere, projection, towerMod, new Vector3(0.522f, 0.014f, -0.173f));
                leftT2.size = towerSize;
                assets.Add(leftT2);//adding

                rightT1 = new Tower(sphere, projection, towerMod, new Vector3(-0.299f, 0.014f, -0.46f));
                rightT1.size = towerSize;
                assets.Add(rightT1);//adding

                rightT2 = new Tower(sphere, projection, towerMod, new Vector3(-0.456f, 0.014f, -0.19f));
                rightT2.size = towerSize;
                assets.Add(rightT2);//adding

                //adding barracks

                leftBarrack = new Entity(sphere,projection, barracksMod, new Vector3(0.165f, 0.04f, -0.553f));
                leftBarrack.size = barrackSize;
                leftBarrack.maxHealth = 3000;
                leftBarrack.health = leftBarrack.maxHealth;
                assets.Add(leftBarrack);

                midBarrack = new Entity(sphere,projection, barracksMod, new Vector3(0.00f, 0.04f, -0.512f));
                midBarrack.size = barrackSize;
                midBarrack.maxHealth = 3000;
                midBarrack.health = midBarrack.maxHealth;
                assets.Add(midBarrack);

                rightBarrack = new Entity(sphere,projection, barracksMod, new Vector3(-0.166f, 0.04f, -0.56f));
                rightBarrack.size = barrackSize;
                rightBarrack.maxHealth = 3000;
                rightBarrack.health = rightBarrack.maxHealth;
                assets.Add(rightBarrack);

                spawnPoint1 = HQ.position+((leftBarrack.position-HQ.position)/2);
                spawnPoint2 = HQ.position + ((midBarrack.position - HQ.position) / 2);
                spawnPoint3 = HQ.position + ((rightBarrack.position - HQ.position) / 2);


                //assets.Add(new Minion(projection, minionMod, spawnPoint1, map, 1,teamColor));
                //assets.Add(new Minion(projection, minionMod, spawnPoint2, map, 2,teamColor));
                //assets.Add(new Minion(projection, minionMod, spawnPoint3, map, 3,teamColor));

              
            }

            #endregion

            #region teamRed
            if (teamColor == Color.Red)
            {

                championMod = Content.Load<Model>("models/redChampion");
                minionMod = Content.Load<Model>("redChar");
                HQmod = Content.Load<Model>("models/redHQ");
                towerMod = Content.Load<Model>("models/redTower");
                barracksMod = Content.Load<Model>("models/redBarracks");

                champ = false;

                HQ = new Entity(sphere,projection, HQmod, new Vector3(0.00f, 0.04f, 0.802f));
                HQ.size = HQsize;
                HQ.maxHealth = 5000;
                HQ.health = HQ.maxHealth;
                assets.Add(HQ);//adding HQ

                hqT1 = new Tower(sphere,projection, towerMod, new Vector3(-0.033f, 0.04f, 0.745f));
                hqT1.size = towerSize;
                assets.Add(hqT1);//adding

                hqT2 = new Tower(sphere, projection, towerMod, new Vector3(0.033f, 0.04f, 0.745f));
                hqT2.size = towerSize;
                assets.Add(hqT2);//adding

                midT1 = new Tower(sphere, projection, towerMod, new Vector3(0.038f, 0.014f, 0.349f));
                midT1.size = towerSize;
                assets.Add(midT1);//adding

                midT2 = new Tower(sphere, projection, towerMod, new Vector3(-0.036f, 0.014f, 0.176f));
                midT2.size = towerSize;
                assets.Add(midT2);//adding

                leftT1 = new Tower(sphere, projection, towerMod, new Vector3(0.243f, 0.014f, 0.42f));
                leftT1.size = towerSize;
                assets.Add(leftT1);//adding

                leftT2 = new Tower(sphere, projection, towerMod, new Vector3(0.522f, 0.014f, 0.173f));
                leftT2.size = towerSize;
                assets.Add(leftT2);//adding

                rightT1 = new Tower(sphere, projection, towerMod, new Vector3(-0.299f, 0.014f, 0.46f));
                rightT1.size = towerSize;
                assets.Add(rightT1);//adding

                rightT2 = new Tower(sphere, projection, towerMod, new Vector3(-0.456f, 0.014f, 0.19f));
                rightT2.size = towerSize;
                assets.Add(rightT2);//adding

                //adding barracks

                leftBarrack = new Entity(sphere,projection, barracksMod, new Vector3(0.165f, 0.04f, 0.553f));
                leftBarrack.size = barrackSize;
                leftBarrack.maxHealth = 3000;
                leftBarrack.health = leftBarrack.maxHealth;
                assets.Add(leftBarrack);

                midBarrack = new Entity(sphere,projection, barracksMod, new Vector3(0.00f, 0.04f, 0.512f));
                midBarrack.size = barrackSize;
                midBarrack.maxHealth = 3000;
                midBarrack.health = midBarrack.maxHealth;
                assets.Add(midBarrack);

                rightBarrack = new Entity(sphere,projection, barracksMod, new Vector3(-0.166f, 0.04f, 0.56f));
                rightBarrack.size = barrackSize;
                rightBarrack.maxHealth = 3000;
                rightBarrack.health = rightBarrack.maxHealth;
                
                assets.Add(rightBarrack);

                spawnPoint1 = HQ.position + ((leftBarrack.position - HQ.position) / 2);
                spawnPoint2 = HQ.position + ((midBarrack.position - HQ.position) / 2);
                spawnPoint3 = HQ.position + ((rightBarrack.position - HQ.position) / 2);


                //champion = new Champion(projection, championMod,spawnPoint2,map,2,teamColor);
                
                //assets.Add(champion);
                //assets.Add(new Minion(projection, minionMod, spawnPoint1, map, 1,teamColor));
                //assets.Add(new Minion(projection, minionMod, spawnPoint2, map, 2,teamColor));
                //assets.Add(new Minion(projection, minionMod, spawnPoint3, map, 3,teamColor));

            }
            //=======HP====================
            healthBar = new Primitives3D.CubePrimitive(GraphicsDevice, 1);
            hpBarScale = 500;
            #endregion
            Color smokeColor = Color.Aqua;

            float smokeDuration = 500;
            effects = (new ParticleSystem(sphere, ref proj, 2, 100, smokeDuration, false, 0.01f, 0.00005f, 0.00009f, smokeColor, true, 0.0001f,
                                                 0.00009f, false, new Vector3(0,0,0), new Vector3(0.00025f, 0.00010f, 0.00025f), new Vector3(0, 0.0002f, 0), new Vector3(0.00005f, 0, 0.00005f), new Vector3(0, 0, 0), 0));

        }//end of constructor


        public void update(GameTime gameTime, List<Entity> enemies) 
        {
         
            
            for (int i = 0; i < assets.Count;++i )
            {
                if(teamColor==Color.Red && assets[i].modelList[0]==minionMod && champion.health>0)
                {
                    //effects.position = champion.position;
                    //effects.Update(gameTime);
                    float distChamp = (assets[i].position - champion.position).Length();
                    if (distChamp < 0.1)
                    {
                        assets[i].boosted = true;
                    }
                    else
                    {
                        assets[i].boosted = false;
                    }

                    
                }
                


                if(assets[i].health<=0)
                {
                    
                    
                    deathAnimation(assets[i]);
              
                }
                //deleting dead people
                assets[i].update(gameTime);
                if (assets[i].dead==true)
                {
                    assets.RemoveAt(i);
                    i--;
                }
               
              }


            selectTarget(enemies);
           
           
            

            spawnMinions(gameTime);
            collision();
            if(teamColor==Color.Red)
            {
                spawnChampion(gameTime);
            }

        }//end of update

        public void draw(Matrix view, Vector3 camPos) 
        {
            for (int i = 0; i < assets.Count;++i)
            {
                assets[i].draw(view);
                hpBarHeight=0.015f;
                ////====depends on each entity change this later====
                //assets[i].health = 100;
                //assets[i].maxHealth = 100;
                //====depends on each entity change this later====


                //assets[i].health = 100;
                //assets[i].maxHealth = 100;
                //====depends on each entity change this later====

                hpBarPercent = assets[i].health / assets[i].maxHealth;
                if (assets[i].modelList[0]== towerMod)
                {
                   hpBarHeight = 0.05f;
                }
                if (assets[i].modelList[0] == HQmod)
                {
                    hpBarHeight = 0.03f;
                }
                if (assets[i].modelList[0] == barracksMod)
                {
                    hpBarHeight = 0.025f;
                }
                if (assets[i].modelList[0] == championMod || assets[i].maxHealth == 3005)
                {
                    hpBarHeight = 0.045f;
                }
                Vector3 camDir = camPos - assets[i].position;
                camDir.Y = 0;
                camDir.Normalize();
                float orientation = -(float)Math.Acos(Vector3.Dot(new Vector3(0, 0, 1), camDir));
                if (camDir.X > 0)
                    orientation *= -1;
                healthWorldRed = Matrix.CreateScale(6 / hpBarScale, 0.9f / hpBarScale, 0.9f / hpBarScale) * Matrix.CreateRotationY(orientation) * Matrix.CreateTranslation(0, hpBarHeight, 0) * Matrix.CreateTranslation(assets[i].position);
                healthBar.Draw(healthWorldRed, view, projection, Color.Red);
                healthWorldGreen = Matrix.CreateScale(hpBarPercent * 6 / hpBarScale, 1 / hpBarScale, 1 / hpBarScale) * Matrix.CreateTranslation(-6 / (hpBarScale * 2) + hpBarPercent * 6 / (hpBarScale * 2), hpBarHeight, 0) * Matrix.CreateRotationY(orientation) * Matrix.CreateTranslation(assets[i].position);
                healthBar.Draw(healthWorldGreen, view, projection, Color.Green);
                
            }
          
      

        }//end of draw


        public void spawnMinions(GameTime gameTime) 
        {
            elapsedTime += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
            if (elapsedTime >= squadTimer)
            {
                
                assets.Add(new Minion(sphere,projection, minionMod, spawnPoint1, map, 1, teamColor));
                assets.Add(new Minion(sphere,projection, minionMod, spawnPoint2, map, 2, teamColor));
                assets.Add(new Minion(sphere,projection, minionMod, spawnPoint3, map, 3, teamColor));
                squadTimer = 500;
                spawnCount++;
                if (spawnCount > 3)
                {
                    squadTimer = TIMER;
                    spawnCount = 0;
                }


                elapsedTime = 0;

            }
        }//end spawnMinions

        public void deathAnimation(Entity e) 
        {
          
            e.dead = true;
        }

        public void selectTarget(List<Entity> enemies) 
        {
            for (int i = 0; i < assets.Count;++i )
            {
                if ((assets[i].target == null) && (assets[i].modelList[0] != HQmod || assets[i].modelList[0] != barracksMod)) 
                {
                    
                    for (int j = 0; j < enemies.Count;++j )
                    {
                        float dist = (enemies[j].position - assets[i].position).Length();
                        if(dist<assets[i].viewRange)
                        {
                            assets[i].target = enemies[j];
                        }
                    }
                }

            }
        }// end of select target

        public void spawnChampion(GameTime gameTime) 
        {
            if(champion!=null && champion.health<=0)
            {
                champ = false;
            }
            if (champ== false)
            {
                champElapsed += (int)gameTime.ElapsedGameTime.TotalMilliseconds;
                if (champElapsed >= champTimer)
                {
                    champion = new Champion(sphere,projection, championMod, spawnPoint2, map, Entity.rand.Next(1,4), teamColor);
                    
                    assets.Add(champion);
                    champ = true;
                    champElapsed = 0;
                }
            }

        }//end of spawnChampion

        public void addPlayer( Entity player) 
        {
            assets.Add(player);
        }

        public void collision() 
        {
            for (int i = 0; i < assets.Count;++i )
            {
                for (int j = 0; j < assets.Count;++j )
                {

                    if(teamColor==Color.Blue && i!=j && assets[i].modelList[0]== minionMod && assets[j].maxHealth==3005)
                    {
                        float distPlayer = (assets[i].position - assets[j].position).Length();
                        if (distPlayer < 0.1) 
                        {
                            assets[i].boosted=true;
                        }
                        else
                            assets[i].boosted = false;
                    }


                    if (i != j && assets[i].modelList[0] != HQmod && assets[i].modelList[0] != towerMod && assets[i].modelList[0]!=barracksMod)
                    {
                        Vector3 dir = assets[i].position - assets[j].position;
                        float dist = dir.Length();
                        float collDist=(assets[i].size/2)+(assets[j].size/2);
                        if (dist < collDist) 
                        {
                            //Vector3 move = Vector3.Cross(assets[i].direction,Vector3.Up);
                            //assets[i].position += move/350;
                            assets[i].position += dir/2;
                        }


                    }
                }
                
            }
        }//end of collision

        
    }
}
